import { KdsConfig } from './../models/kdsConfig';
import { ServiceBase } from './../services/base';
import { ServiceBaseX } from './../services/order';
import * as guid from 'uuid/v1';
import { Orderitem, Order } from './../models/order';
import { BehaviorSubject } from 'rxjs';
import { localstorageDao } from './../utils/localstorage';
import { ExpeditionOrder, ExpeditionOrderItem } from './../models/expeditionOrder';
import * as R from "ramda";

export class ExpeditionOrderDishManage {
    expeditionOrder: ExpeditionOrder;
    observable: BehaviorSubject<ExpeditionOrder>;

    static current = new ExpeditionOrderDishManage();

    constructor() {
        this.init();
    }

    init() {
        let expeditionOrder = this.fromCache();
        // if (!expeditionOrder) expeditionOrder = this.generateExpeditionOrder();
        this.expeditionOrder = expeditionOrder;
        this.observable = new BehaviorSubject(expeditionOrder);
    }

    generateExpeditionOrder(serialNO?): ExpeditionOrder {
        const currentDevice = ServiceBaseX.prototype.currentDevice;
        const currentKitchenSolutions = ServiceBaseX.prototype.currentKitchenSolutions;
        const kdsConfig:KdsConfig = JSON.parse(localStorage.getItem("kdsConfig") || "{}")
        return <any>{
            serialNo: serialNO || "default",
            items: [],
            kitchenOrderIds:[],
            sourceTerminalId: currentDevice && currentDevice.id,
            extend: {
                kitchenSolutions: currentKitchenSolutions && currentKitchenSolutions.map(x => {
                    return {
                        id: x.id, name: x.name
                    }
                }),
                QRCodePrinted:kdsConfig.expeditionOrderConfig&&kdsConfig.expeditionOrderConfig.QRCodePrinted
            },
            terminalId:ServiceBase.prototype.Terminal&&ServiceBase.prototype.Terminal.id
        }
    }

    clear() {
        this.expeditionOrder = <any>{};
        this.notify();
    }

    async resetExpeditionOrder(serialNO?) {
        if (!serialNO) {
            const result = (await ServiceBaseX.prototype.generateExpeditionOrderSerialNo());
            serialNO = result.serialNO;
        }
        this.expeditionOrder = this.generateExpeditionOrder(serialNO);
        this.notify();
    }

    save() { }

    notify() {
        this.observable.next(this.expeditionOrder);
    }

    fromCache(): ExpeditionOrder {
        return localstorageDao.get("ExpeditionOrder")
    }

    addExpeditionOrderItem(expeditionOrderItem: ExpeditionOrderItem) {
        this.expeditionOrder.items.push(expeditionOrderItem);
        this.notify();
    }

    removeExpeditionOrderItem(expeditionOrderItem: ExpeditionOrderItem) {
        this.expeditionOrder.items = this.expeditionOrder.items.filter(item => item.id != expeditionOrderItem.id);
        this.notify();
    }


    addKitchenOrderItem(order: Order, itemId: string, qty?: number) {
        const item = order.items.find(item => item.id == itemId);
        const expeditionOrdeItem: ExpeditionOrderItem = {
            id: guid(),
            kitchenOrderId: order.id,
            kitchenOrderItemId: item.id,
            inventoryId: item.inventoryId,
            inventoryName: item.inventoryName,
            inventoryCode: item.inventoryCode,
            customerIdentity: order.customerIdentity,
            qty: item.qty,
            refundQty: item.refundQty,
            remindCount: item.remindCount,
            modifiers: item.modifiers,
            description: item.description,
            extended: {
                categories: item.categories,
                table:order.extended&&order.extended.table,
                receiveTime:order.receiveTime
            },
            tableId:order.extended&&order.extended.table&&order.extended.table.id
        }
        const kitchenOrderIds = this.expeditionOrder.kitchenOrderIds;
        kitchenOrderIds.push(order.id);
        this.expeditionOrder.kitchenOrderIds = R.uniq(kitchenOrderIds); 
        this.addExpeditionOrderItem(expeditionOrdeItem);
    }

    updateExpeditionOrderItemsByKitchenOrder(kitchenOrder: Order) {
        const foundItems = this.expeditionOrder.items.filter(item => item.kitchenOrderId == kitchenOrder.id);
        if (foundItems.length == 0) return;
        foundItems.forEach(item => {
            const kitchenOrderItem = kitchenOrder.items.find(kitchenOrderItem => kitchenOrderItem.id == item.kitchenOrderItemId);
            item.customerIdentity = kitchenOrder.customerIdentity;
            item.refundQty = kitchenOrderItem.refundQty;
            item.remindCount = kitchenOrderItem.remindCount;
            if(item.qty != kitchenOrderItem.qty){
                const addItemIds = this.getKitchenOrderItemsByLastItem(item, kitchenOrder.items).map(x=>x.id);
                addItemIds.forEach(id=>{
                    this.addKitchenOrderItem(kitchenOrder, id);
                })
                item.qty = kitchenOrderItem.qty;
            }
        });
        this.expeditionOrder.items = this.expeditionOrder.items.filter(item => item.qty);
        this.notify();
    }

    getKitchenOrderItemsByLastItem(expeditionOrderItem:ExpeditionOrderItem, kitchenOrderItems:Orderitem[]){
        const items:Orderitem[] = [];
        const referKitchenOrderItems = kitchenOrderItems.filter(item=>item.id.includes(expeditionOrderItem.kitchenOrderItemId) && expeditionOrderItem.kitchenOrderItemId!=item.id).sort((x,y)=>x.createTime - y.createTime);
        const currentKitchenOrderItem =  kitchenOrderItems.find(x=>x.id==expeditionOrderItem.kitchenOrderItemId)
        while (kitchenOrderItems.length&& (expeditionOrderItem.qty - currentKitchenOrderItem.qty) > items.map(x=>x.refundQty).reduce((x,y)=>x+y,0)) {
            items.push(referKitchenOrderItems.pop());
        }
       return items;
    }
}

